home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xmmix-1.1
/
widget.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-05
|
32KB
|
1,162 lines
/*
* xmmix - Motif(tm) Audio Mixer
*
* Copyright (C) 1995 Ti Kan
* E-mail: ti@amb.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef LINT
static char *_widget_c_ident_ = "@(#)widget.c 2.5 95/05/12";
#endif
#include "appenv.h"
#include "widget.h"
#include "mixer.h"
#include "xmmix.xbm"
extern appdata_t app_data;
extern widgets_t widgets;
extern int maxdevs;
#define CTL_DISTANCE 48
#define PD_FILE_LOAD 0
#define PD_FILE_SAVE 1
#define PD_FILE_SEP 2
#define PD_FILE_EXIT 3
STATIC btinfo_t file_btinfo[] = {
{ NULL, "Load...", "loadButton", "l", "L" },
{ NULL, "Save...", "saveButton", "s", "S" },
{ NULL, NULL, "fileSeparator", NULL, NULL },
{ NULL, "Exit", "exitButton", "x", "x" },
{ NULL, NULL, NULL, NULL, NULL },
};
#define PD_OPTS_RESET 0
STATIC btinfo_t options_btinfo[] = {
{ NULL, "Reset", "resetButton", "r", "R" },
{ NULL, NULL, NULL, NULL, NULL },
};
#define PD_HELP_MANPG 0
#define PD_HELP_ABOUT 1
STATIC btinfo_t help_btinfo[] = {
{ NULL, "Man page...", "manPageButton", "m", "M" },
{ NULL, "About...", "aboutButton", "a", "A" },
{ NULL, NULL, NULL, NULL, NULL },
};
STATIC pdinfo_t file_pd = {
NULL, "File", "file", "f", "F", file_btinfo
};
STATIC pdinfo_t opts_pd = {
NULL, "Options", "options", "o", "O", options_btinfo
};
STATIC pdinfo_t help_pd = {
NULL, "Help", "help", "h", "H", help_btinfo
};
STATIC slinfo_t slinfo[] = {
{ /* 0 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Master", "master", CTL_OUTPUT, 17, TRUE, FALSE
},
{ /* 1 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Bass", "bass", CTL_MISC, 10, TRUE, FALSE
},
{ /* 2 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Treble", "treble", CTL_MISC, 11, TRUE, FALSE
},
{ /* 3 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Synth", "synth", CTL_INPUT, 1, TRUE, TRUE
},
{ /* 4 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"PCM", "pcm", CTL_INPUT, 2, TRUE, TRUE
},
{ /* 5 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Speaker", "speaker", CTL_OUTPUT, 16, TRUE, FALSE
},
{ /* 6 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Line", "line", CTL_INPUT, 4, TRUE, TRUE
},
{ /* 7 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Mic", "mic", CTL_INPUT, 8, TRUE, TRUE
},
{ /* 8 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"CD", "cd", CTL_INPUT, 9, TRUE, TRUE
},
{ /* 9 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Rec Mon", "recmon", CTL_OUTPUT, 12, TRUE, FALSE
},
{ /* 10 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Alt PCM", "altpcm", CTL_INPUT, 3, TRUE, TRUE
},
{ /* 11 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Rec Out", "recout", CTL_OUTPUT, 13, TRUE, FALSE
},
{ /* 12 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"In Gain", "igain", CTL_MISC, 14, TRUE, FALSE
},
{ /* 13 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Out Gain", "ogain", CTL_MISC, 15, TRUE, FALSE
},
{ /* 14 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Line-1", "line1", CTL_INPUT, 5, TRUE, TRUE
},
{ /* 15 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Line-2", "line2", CTL_INPUT, 6, TRUE, TRUE
},
{ /* 16 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Line-3", "line3", CTL_INPUT, 7, TRUE, TRUE
},
{ /* 17 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 18 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 19 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 20 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 21 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 22 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 23 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 24 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 25 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 26 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 27 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 28 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 29 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 30 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
},
{ /* 31 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, FALSE, FALSE
}
};
STATIC XmString xs_lock,
xs_rec,
xs_left,
xs_right;
STATIC Atom delw;
/***********************
* internal routines *
***********************/
/*
* Widget-related functions
*/
/*
* create_pdmnu
* Create a pulldown menu
*
* Args:
* parent - The parent widget
* pd - The pulldown menu info structure
*
* Return:
* The menu widget
*/
STATIC Widget
create_pdmnu(Widget parent, pdinfo_t *pd)
{
int i,
n;
Arg arg[10];
XmString xs;
XmString xs_acc;
char wname[STR_BUF_SZ];
Widget ret_widget;
/* Create File pulldown menu */
sprintf(wname, "%sMenu", pd->name);
ret_widget = XmCreatePulldownMenu(parent, wname, NULL, 0);
for (i = 0; pd->btip[i].name != NULL; i++) {
n = 0;
if (pd->btip[i].label == NULL) {
/* Separator */
pd->btip[i].widget = XmCreateSeparator(
ret_widget, pd->btip[i].name, NULL, 0
);
XtManageChild(pd->btip[i].widget);
}
else {
/* Button */
if (pd->btip[i].label != NULL) {
xs = XmStringCreateSimple(pd->btip[i].label);
XtSetArg(arg[n], XmNlabelString, xs); n++;
}
if (pd->btip[i].acc != NULL) {
xs_acc = XmStringCreateSimple(pd->btip[i].acc);
XtSetArg(arg[n], XmNaccelerator, xs_acc); n++;
}
if (pd->btip[i].mne != NULL) {
XtSetArg(arg[n], XmNmnemonic,
XStringToKeysym(pd->btip[i].mne)); n++;
}
pd->btip[i].widget = XmCreatePushButton(
ret_widget, pd->btip[i].name, arg, n
);
XtManageChild(pd->btip[i].widget);
if (pd->btip[i].label != NULL)
XmStringFree(xs);
if (pd->btip[i].acc != NULL)
XmStringFree(xs_acc);
}
}
/* Create cascade button as menu activator */
sprintf(wname, "%sButton", pd->name);
n = 0;
if (pd->label != NULL) {
xs = XmStringCreateSimple(pd->label);
XtSetArg(arg[n], XmNlabelString, xs); n++;
}
if (pd->acc != NULL) {
xs_acc = XmStringCreateSimple(pd->acc);
XtSetArg(arg[n], XmNaccelerator, xs_acc); n++;
}
if (pd->mne != NULL) {
XtSetArg(arg[n], XmNmnemonic, XStringToKeysym(pd->mne)); n++;
}
XtSetArg(arg[n], XmNsubMenuId, ret_widget); n++;
pd->widget = XmCreateCascadeButton(parent, wname, arg, n);
XtManageChild(pd->widget);
if (pd->label != NULL)
XmStringFree(xs);
if (pd->acc != NULL)
XmStringFree(xs_acc);
return (ret_widget);
}
/*
* create_vert_controls
* Create a group of mixer controls including the vertical slider
* and associated toggle buttons and labels.
*
* Args:
* m - Pointer to the main widgets structure
* dev - The mixer control device index
* y1 - The top reference position (percent)
* y2 - The bottom reference position (percent)
* pos - The display position number
* tot - Total number of controls to be displayed
*
* Return:
* Nothing
*/
STATIC void
create_vert_controls(widgets_t *m, int dev, int y1, int y2, int pos, int tot)
{
int x,
n;
Arg arg[20];
char wname[STR_BUF_SZ];
XmString xs;
x = CTL_DISTANCE * pos;
/* Right slider */
sprintf(wname, "%sRightScale", slinfo[dev].name);
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNleftOffset, x); n++;
XtSetArg(arg[n], XmNtopPosition, y1); n++;
XtSetArg(arg[n], XmNbottomPosition, y2); n++;
XtSetArg(arg[n], XmNshowValue, False); n++;
XtSetArg(arg[n], XmNorientation, XmVERTICAL); n++;
XtSetArg(arg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++;
XtSetArg(arg[n], XmNminimum, 0); n++;
XtSetArg(arg[n], XmNmaximum, 100); n++;
XtSetArg(arg[n], XmNhighlightOnEnter, True); n++;
slinfo[dev].widget_r = XmCreateScale(m->form, wname, arg, n);
XtManageChild(slinfo[dev].widget_r);
/* Left slider */
sprintf(wname, "%sLeftScale", slinfo[dev].name);
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
XtSetArg(arg[n], XmNtopPosition, y1); n++;
XtSetArg(arg[n], XmNbottomPosition, y2); n++;
XtSetArg(arg[n], XmNshowValue, False); n++;
XtSetArg(arg[n], XmNorientation, XmVERTICAL); n++;
XtSetArg(arg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++;
XtSetArg(arg[n], XmNminimum, 0); n++;
XtSetArg(arg[n], XmNmaximum, 100); n++;
XtSetArg(arg[n], XmNhighlightOnEnter, True); n++;
slinfo[dev].widget_l = XmCreateScale(m->form, wname, arg, n);
XtManageChild(slinfo[dev].widget_l);
/* Left label */
sprintf(wname, "%sLeftLabel", slinfo[dev].name);
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++;
XtSetArg(arg[n], XmNtopPosition, y1 - 4); n++;
XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_l); n++;
XtSetArg(arg[n], XmNlabelString, xs_left); n++;
slinfo[dev].widget_lbl_l = XmCreateLabel(
m->form, wname, arg, n
);
XtManageChild(slinfo[dev].widget_lbl_l);
/* Right label */
sprintf(wname, "%sRightLabel", slinfo[dev].name);
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
XtSetArg(arg[n], XmNtopPosition, y1 - 4); n++;
XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_r); n++;
XtSetArg(arg[n], XmNlabelString, xs_right); n++;
slinfo[dev].widget_lbl_r = XmCreateLabel(
m->form, wname, arg, n
);
XtManageChild(slinfo[dev].widget_lbl_r);
/* Slider label */
sprintf(wname, "%sLabel", slinfo[dev].name);
xs = XmStringCreateSimple(slinfo[dev].label);
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_lbl_l); n++;
XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_lbl_r); n++;
XtSetArg(arg[n], XmNleftOffset, -4); n++;
XtSetArg(arg[n], XmNrightOffset, -4); n++;
XtSetArg(arg[n], XmNtopWidget, m->menu_bar); n++;
XtSetArg(arg[n], XmNtopOffset, 3); n++;
XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_lbl_l); n++;
XtSetArg(arg[n], XmNlabelString, xs); n++;
slinfo[dev].widget_lbl = XmCreateLabel(
m->form, slinfo[dev].name, arg, n
);
XtManageChild(slinfo[dev].widget_lbl);
XmStringFree(xs);
/* Lock button */
sprintf(wname, "%sLockButton", slinfo[dev].name);
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++;
XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
XtSetArg(arg[n], XmNtopWidget, slinfo[dev].widget_l); n++;
XtSetArg(arg[n], XmNlabelString, xs_lock); n++;
slinfo[dev].widget_lock_btn = XmCreateToggleButton(
m->form, wname, arg, n
);
XtManageChild(slinfo[dev].widget_lock_btn);
/* Record selector buttons */
if (slinfo[dev].recsupp) {
sprintf(wname, "%sRecButton", slinfo[dev].name);
n = 0;
XtSetArg(arg[n], XmNleftAttachment,
XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNrightAttachment,
XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++;
XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
XtSetArg(arg[n], XmNtopWidget,
slinfo[dev].widget_lock_btn); n++;
XtSetArg(arg[n], XmNlabelString, xs_rec); n++;
slinfo[dev].widget_rec_btn = XmCreateToggleButton(
m->form, wname, arg, n
);
XtManageChild(slinfo[dev].widget_rec_btn);
}
}
/*
* bm_to_px
* Convert a bitmap into a pixmap.
*
* Args:
* w - A widget the pixmap should be associated with
* bits - Pointer to the raw bitmap data
* width, height - The resultant pixmap dimensions
*
* Return:
* The pixmap ID, or NULL if failure.
*/
Pixmap
bm_to_px(Widget w, void *bits, int width, int height, int depth)
{
Display *display = XtDisplay(w);
Window window = XtWindow(w);
int screen = DefaultScreen(display);
GC pixmap_gc;
XGCValues val;
Pixmap tmp_bitmap;
static Pixmap ret_pixmap;
tmp_bitmap = XCreateBitmapFromData(
display, window, (char *) bits, width, height
);
if (tmp_bitmap == (Pixmap) NULL)
return ((Pixmap) NULL);
if (depth == 1) {
ret_pixmap = tmp_bitmap;
return (ret_pixmap);
}
/* Create pixmap with depth */
ret_pixmap = XCreatePixmap(display, window, width, height, depth);
if (ret_pixmap == (Pixmap) NULL)
return ((Pixmap) NULL);
/* Allocate colors for pixmap if on color screen */
if (DisplayCells(display, screen) > 2) {
/* Get pixmap color configuration */
XtVaGetValues(w,
XmNforeground, &val.foreground,
XmNbackground, &val.background,
NULL
);
/* Create GC for pixmap */
pixmap_gc = XCreateGC(
display, window, GCForeground | GCBackground, &val
);
}
else
pixmap_gc = DefaultGC(display, screen);
/* Copy bitmap into pixmap */
XCopyPlane(display, tmp_bitmap, ret_pixmap, pixmap_gc,
0, 0, width, height, 0, 0, 1);
/* No need for the bitmap any more, so free it */
XFreePixmap(display, tmp_bitmap);
return (ret_pixmap);
}
/***********************
* public routines *
***********************/
/*
* widget_init
* Initialize widget-related structures.
*
* Args:
* m - Pointer to the main widgets structure
*
* Return:
* Nothing
*/
void
widget_init(widgets_t *m)
{
/* Initialize structures */
m->sl = slinfo;
m->file_pd = &file_pd;
m->opts_pd = &opts_pd;
m->help_pd = &help_pd;
}
/*
* create_widgets
* Top-level function to create all widgets.
*
* Args:
* m - Pointer to the main widgets structure
*
* Return:
* Nothing
*/
void
create_widgets(widgets_t *m)
{
int i, j, k, n,
ctls,
form_width;
Arg arg[20];
char wname[STR_BUF_SZ],
str[STR_BUF_SZ];
XmString xs;
/* Count the number of slider controls we will display */
for (i = 0, ctls = 0; i < maxdevs; i++) {
if (slinfo[i].supp)
ctls++;
}
/* Create compound strings that will be used repetitively */
xs_left = XmStringCreateSimple("L");
xs_right = XmStringCreateSimple("R");
xs_lock = XmStringCreateSimple("lock");
xs_rec = XmStringCreateSimple("rec");
/* Create form widget as container */
if ((form_width = (ctls + 1) * CTL_DISTANCE) < 300)
form_width = 300;
n = 0;
XtSetArg(arg[n], XmNwidth, form_width); n++;
XtSetArg(arg[n], XmNheight, 320); n++;
XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++;
m->form = XmCreateForm(m->toplevel, "mainForm", arg, n);
XtManageChild(m->form);
/* Create logo label */
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNleftOffset, (form_width/2) - (xmmix_width/2)); n++;
XtSetArg(arg[n], XmNtopPosition, 88); n++;
XtSetArg(arg[n], XmNlabelType, XmPIXMAP); n++;
XtSetArg(arg[n], XmNmarginHeight, 0); n++;
XtSetArg(arg[n], XmNmarginWidth, 0); n++;
XtSetArg(arg[n], XmNhighlightThickness, 0); n++;
XtSetArg(arg[n], XmNwidth, xmmix_width); n++;
XtSetArg(arg[n], XmNheight, xmmix_height); n++;
m->logolbl = XmCreateLabel(m->form, "logoLabel", arg, n);
XtManageChild(m->logolbl);
/* Create menu bar */
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
m->menu_bar = XmCreateMenuBar(m->form, "menuBar", arg, n);
XtManageChild(m->menu_bar);
/* Create File pulldown menu */
m->file_mnu = create_pdmnu(m->menu_bar, &file_pd);
/* Create Options pulldown menu */
m->options_mnu = create_pdmnu(m->menu_bar, &opts_pd);
/* Create Help pulldown menu */
m->help_mnu = create_pdmnu(m->menu_bar, &help_pd);
XtVaSetValues(m->menu_bar,
XmNmenuHelpWidget, help_pd.widget,
NULL
);
/* Create all sliders and associated labels and buttons */
for (j = 1, k = 0; j <= MAXDEVS; j++) {
for (i = 0; i < maxdevs; i++) {
if (j == slinfo[i].order && slinfo[i].supp) {
create_vert_controls(m, i, 22, 70, ++k, ctls);
}
}
}
/* Horizontal separator */
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNtopPosition, 84); n++;
XtSetArg(arg[n], XmNleftOffset, 1); n++;
XtSetArg(arg[n], XmNrightOffset, 1); n++;
XtSetArg(arg[n], XmNorientation, XmHORIZONTAL); n++;
m->hsep = XmCreateSeparator(m->form, "horizontalSeparator", arg, n);
XtManageChild(m->hsep);
/*
* Flat button
*/
if (slinfo[SOUND_MIXER_BASS].supp || slinfo[SOUND_MIXER_TREBLE].supp) {
xs = XmStringCreateSimple("Flat");
n = 0;
XtSetArg(arg[n], XmNleftAttachment,
XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNrightAttachment,
XmATTACH_OPPOSITE_WIDGET); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
if (slinfo[SOUND_MIXER_BASS].supp) {
XtSetArg(arg[n], XmNleftWidget,
m->sl[SOUND_MIXER_BASS].widget_l); n++;
XtSetArg(arg[n], XmNtopWidget,
m->sl[SOUND_MIXER_BASS].widget_lock_btn); n++;
}
else {
XtSetArg(arg[n], XmNleftWidget,
m->sl[SOUND_MIXER_TREBLE].widget_l); n++;
XtSetArg(arg[n], XmNtopWidget,
m->sl[SOUND_MIXER_TREBLE].widget_lock_btn); n++;
}
if (slinfo[SOUND_MIXER_TREBLE].supp) {
XtSetArg(arg[n], XmNrightWidget,
m->sl[SOUND_MIXER_TREBLE].widget_r); n++;
XtSetArg(arg[n], XmNtopWidget,
m->sl[SOUND_MIXER_TREBLE].widget_lock_btn); n++;
}
else {
XtSetArg(arg[n], XmNrightWidget,
m->sl[SOUND_MIXER_BASS].widget_r); n++;
XtSetArg(arg[n], XmNtopWidget,
m->sl[SOUND_MIXER_BASS].widget_lock_btn); n++;
}
XtSetArg(arg[n], XmNlabelString, xs); n++;
m->flat_btn = XmCreatePushButton(m->form, "flatButton", arg, n);
XtManageChild(m->flat_btn);
XmStringFree(xs);
}
/*
* Mute button
*/
if (m->mute_supp) {
xs = XmStringCreateSimple("Mute");
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNleftOffset, form_width - 100); n++;
XtSetArg(arg[n], XmNtopPosition, 87); n++;
XtSetArg(arg[n], XmNbottomPosition, 92); n++;
XtSetArg(arg[n], XmNwidth, 66); n++;
XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
XtSetArg(arg[n], XmNlabelString, xs); n++;
m->mute_btn = XmCreateToggleButton(
m->form, "muteButton", arg, n
);
XtManageChild(m->mute_btn);
XmStringFree(xs);
}
/*
* Loudness button
*/
if (m->loud_supp) {
xs = XmStringCreateSimple("Loudness");
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNleftOffset, form_width - 100); n++;
XtSetArg(arg[n], XmNtopPosition, 92); n++;
XtSetArg(arg[n], XmNbottomPosition, 97); n++;
XtSetArg(arg[n], XmNwidth, 66); n++;
XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
XtSetArg(arg[n], XmNlabelString, xs); n++;
m->loud_btn = XmCreateToggleButton(
m->form, "loudnessButton", arg, n
);
XtManageChild(m->loud_btn);
XmStringFree(xs);
}
/*
* Enhance option menu
*/
if (m->enh_supp) {
m->enh_mnu = XmCreatePulldownMenu(
m->form, "enhancePulldownMenu", NULL, 0
);
for (i = 0; i < NENHANCE; i++) {
sprintf(wname, "enhanceButton%d", i);
sprintf(str, "%d", i);
xs = XmStringCreateSimple(str);
n = 0;
XtSetArg(arg[n], XmNlabelString, xs); n++;
m->enh_btn[i] = XmCreatePushButton(
m->enh_mnu, wname, arg, n
);
XtManageChild(m->enh_btn[i]);
XmStringFree(xs);
}
xs = XmStringCreateSimple("Enhance");
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNleftOffset, 28); n++;
XtSetArg(arg[n], XmNtopPosition, 88); n++;
XtSetArg(arg[n], XmNsubMenuId, m->enh_mnu); n++;
m->enh_opt = XmCreateOptionMenu(
m->form, "enhanceOptionMenu", arg, n
);
XtVaSetValues(
XmOptionLabelGadget(m->enh_opt),
XmNlabelString, xs,
NULL
);
XtManageChild(m->enh_opt);
XmStringFree(xs);
}
/*
* File selection box form
*/
n = 0;
XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++;
XtSetArg(arg[n], XmNautoUnmanage, False); n++;
XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
XtSetArg(arg[n], XmNwidth, 330); n++;
XtSetArg(arg[n], XmNheight, 370); n++;
m->fsform = XmCreateFormDialog(
m->toplevel, "fileSelectionForm", arg, n
);
/*
* File selection box
*/
xs = XmStringCreateSimple("*.mxr");
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNmustMatch, False); n++;
XtSetArg(arg[n], XmNpattern, xs); n++;
m->fsbox = XmCreateFileSelectionBox(
m->fsform, "fileSelectionBox", arg, n
);
XtUnmanageChild(
XmFileSelectionBoxGetChild(m->fsbox, XmDIALOG_HELP_BUTTON)
);
XtManageChild(m->fsbox);
XmStringFree(xs);
XmStringFree(xs_left);
XmStringFree(xs_right);
XmStringFree(xs_lock);
XmStringFree(xs_rec);
/*
* Man page window widgets
*/
/* Create form widget as container */
xs = XmStringCreateSimple("Xmmix Help");
n = 0;
XtSetArg(arg[n], XmNdialogTitle, xs); n++;
XtSetArg(arg[n], XmNautoUnmanage, True); n++;
XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++;
XtSetArg(arg[n], XmNwidth, 460); n++;
XtSetArg(arg[n], XmNheight, 340); n++;
m->helpform = XmCreateFormDialog(m->form, "helpForm", arg, n);
XmStringFree(xs);
/* Create text widget as help text viewer */
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNleftPosition, 2); n++;
XtSetArg(arg[n], XmNrightPosition, 98); n++;
XtSetArg(arg[n], XmNtopPosition, 4); n++;
XtSetArg(arg[n], XmNbottomPosition, 81); n++;
XtSetArg(arg[n], XmNeditable, False); n++;
XtSetArg(arg[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
XtSetArg(arg[n], XmNcursorPositionVisible, False); n++;
XtSetArg(arg[n], XmNcursorPosition, 0); n++;
m->helptxt = XmCreateScrolledText(m->helpform, "helpText", arg, n);
XtManageChild(m->helptxt);
/* Create separator bar widget */
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNleftOffset, 2); n++;
XtSetArg(arg[n], XmNrightOffset, 2); n++;
XtSetArg(arg[n], XmNtopPosition, 84); n++;
m->helpsep = XmCreateSeparator(m->helpform, "helpSeparator", arg, n);
XtManageChild(m->helpsep);
/* Create pushbutton widget as OK button */
xs = XmStringCreateSimple("OK");
n = 0;
XtSetArg(arg[n], XmNleftAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNrightAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
XtSetArg(arg[n], XmNleftPosition, 44); n++;
XtSetArg(arg[n], XmNrightPosition, 56); n++;
XtSetArg(arg[n], XmNtopPosition, 89); n++;
XtSetArg(arg[n], XmNlabelString, xs); n++;
m->helpok_btn = XmCreatePushButton(
m->helpform, "helpOkButton", arg, n
);
XtManageChild(m->helpok_btn);
XmStringFree(xs);
/*
* Info dialog widget for the About popup
*/
xs = XmStringCreateSimple("About");
n = 0;
XtSetArg(arg[n], XmNdialogTitle, xs); n++;
XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_MODELESS); n++;
m->about = XmCreateInformationDialog(
m->toplevel, "aboutDialog", arg, n
);
XtUnmanageChild(
XmMessageBoxGetChild(m->about, XmDIALOG_HELP_BUTTON)
);
XtUnmanageChild(
XmMessageBoxGetChild(m->about, XmDIALOG_CANCEL_BUTTON)
);
XmStringFree(xs);
/*
* Info dialog widget for warning popups
*/
xs = XmStringCreateSimple("Warning");
n = 0;
XtSetArg(arg[n], XmNdialogTitle, xs); n++;
XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
m->warning = XmCreateWarningDialog(
m->toplevel, "warningDialog", arg, n
);
XtUnmanageChild(
XmMessageBoxGetChild(m->warning, XmDIALOG_HELP_BUTTON)
);
XtUnmanageChild(
XmMessageBoxGetChild(m->warning, XmDIALOG_CANCEL_BUTTON)
);
XmStringFree(xs);
}
/*
* post_realize_config
* Top-level function to perform set-up and initialization tasks
* after realizing all widgets.
*
* Args:
* m - Pointer to the main widgets structure
*
* Return:
* Nothing
*/
void
post_realize_config(widgets_t *m)
{
int i, n;
Display *display = XtDisplay(m->toplevel);
Pixmap px;
char title[STR_BUF_SZ],
*p;
/* Set main window title bar string */
if (app_data.demo)
strcpy(title, "Motif Audio Mixer (Demo)");
else {
n = 0;
if ((i = strlen(app_data.device)) > 0) {
/* Find mixer device number */
p = app_data.device + i;
while (p > app_data.device) {
if (!isdigit(*(p - 1)))
break;
p--;
}
if (isdigit(*p))
n = atoi(p);
}
sprintf(title, "Motif Audio Mixer %d", n);
}
XStoreName(display, XtWindow(m->toplevel), title);
/*
* Create logo pixmap
*/
px = bm_to_px(m->logolbl, xmmix_bits, xmmix_width, xmmix_height, 1);
XtVaSetValues(m->toplevel, XmNiconPixmap, px, NULL);
px = bm_to_px(m->logolbl, xmmix_bits, xmmix_width, xmmix_height,
DefaultDepth(display, DefaultScreen(display)));
XtVaSetValues(m->logolbl, XmNlabelPixmap, px, NULL);
XtVaSetValues(m->about, XmNsymbolPixmap, px, NULL);
/* Get WM_DELETE_WINDOW atom */
delw = XmInternAtom(display, "WM_DELETE_WINDOW", False);
}
/*
* register_callbacks
* Top-level function to register all callback routines.
*
* Args:
* m - Pointer to the main widgets structure
*
* Return:
* Nothing
*/
void
register_callbacks(widgets_t *m)
{
int i;
/*
* Main window callbacks
*/
/* Callbacks for each control group */
for (i = 0; i < maxdevs; i++) {
if (!slinfo[i].supp)
continue;
/* Left Slider callbacks */
XtAddCallback(slinfo[i].widget_l,
XmNvalueChangedCallback,
(XtCallbackProc) mx_slider_l, (XtPointer) i
);
XtAddCallback(slinfo[i].widget_l,
XmNdragCallback,
(XtCallbackProc) mx_slider_l, (XtPointer) i
);
/* Right Slider callbacks */
XtAddCallback(slinfo[i].widget_r,
XmNvalueChangedCallback,
(XtCallbackProc) mx_slider_r, (XtPointer) i
);
XtAddCallback(slinfo[i].widget_r,
XmNdragCallback,
(XtCallbackProc) mx_slider_r, (XtPointer) i
);
/* Lock button callback */
XtAddCallback(slinfo[i].widget_lock_btn,
XmNvalueChangedCallback,
(XtCallbackProc) mx_lock_btn, (XtPointer) i
);
/* Rec button callback */
if (slinfo[i].recsupp) {
XtAddCallback(slinfo[i].widget_rec_btn,
XmNvalueChangedCallback,
(XtCallbackProc) mx_rec_btn, (XtPointer) i
);
}
}
/* Flat button callback */
if (slinfo[SOUND_MIXER_BASS].supp || slinfo[SOUND_MIXER_TREBLE].supp) {
XtAddCallback(m->flat_btn,
XmNactivateCallback,
(XtCallbackProc) mx_flat_btn, NULL
);
}
/* Mute button callback */
if (m->mute_supp) {
XtAddCallback(m->mute_btn,
XmNvalueChangedCallback,
(XtCallbackProc) mx_mute_btn, NULL
);
}
/* Loudness button callback */
if (m->loud_supp) {
XtAddCallback(m->loud_btn,
XmNvalueChangedCallback,
(XtCallbackProc) mx_loud_btn, NULL
);
}
/* Stereo enhance button callbacks */
if (m->enh_supp) {
for (i = 0; i < NENHANCE; i++) {
XtAddCallback(m->enh_btn[i],
XmNactivateCallback,
(XtCallbackProc) mx_enhance_btn, (XtPointer) i
);
}
}
/* Load button callback */
XtAddCallback(file_pd.btip[PD_FILE_LOAD].widget,
XmNactivateCallback,
(XtCallbackProc) mx_load, NULL
);
/* Save button callback */
XtAddCallback(file_pd.btip[PD_FILE_SAVE].widget,
XmNactivateCallback,
(XtCallbackProc) mx_save, NULL
);
/* Exit button callback */
XtAddCallback(file_pd.btip[PD_FILE_EXIT].widget,
XmNactivateCallback,
(XtCallbackProc) mx_exit, NULL
);
/* Reset button callback */
XtAddCallback(opts_pd.btip[PD_OPTS_RESET].widget,
XmNactivateCallback,
(XtCallbackProc) mx_reset, NULL
);
/* Man Page button callback */
XtAddCallback(help_pd.btip[PD_HELP_MANPG].widget,
XmNactivateCallback,
(XtCallbackProc) mx_manpg, NULL
);
/* About button callback */
XtAddCallback(help_pd.btip[PD_HELP_ABOUT].widget,
XmNactivateCallback,
(XtCallbackProc) mx_about, NULL
);
/*
* File Selection Box callbacks
*/
/* OK button callback */
XtAddCallback(m->fsbox,
XmNokCallback,
(XtCallbackProc) mx_fsok_btn, NULL
);
/* Cancel button callback */
XtAddCallback(m->fsbox,
XmNcancelCallback,
(XtCallbackProc) mx_fscancel_btn, NULL
);
/*
* Focus change callback
*/
XtAddCallback(m->form,
XmNfocusCallback,
(XtCallbackProc) mx_focuschg, (XtPointer) m->form
);
/*
* Install WM_DELETE_WINDOW handler
*/
XmAddWMProtocolCallback(
m->toplevel,
delw,
(XtCallbackProc) mx_exit, (XtPointer) NULL
);
}